home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #5 / Amiga Plus CD - 2000 - No. 5.iso / Tools / Dev / lame_src / vorbis_interface.c < prev    next >
C/C++ Source or Header  |  2000-01-01  |  14KB  |  495 lines

  1. /* LAME interface to libvorbis */
  2.  
  3. #ifdef HAVEVORBIS
  4. #include <time.h>
  5. #include "vorbis/codec.h"
  6. #include "vorbis/modes.h"
  7. #include "lame.h"
  8. #include "util.h"
  9.  
  10. int16_t convbuffer[4096]; /* take 8k out of the data segment, not the stack */
  11. int convsize;
  12.  
  13. ogg_sync_state   oy; /* sync and verify incoming physical bitstream */
  14. ogg_stream_state os; /* take physical pages, weld into a logical
  15.             stream of packets */
  16. ogg_page         og; /* one Ogg bitstream page.  Vorbis packets are inside */
  17. ogg_packet       op; /* one raw packet of data for decode */
  18.  
  19. vorbis_info      vi; /* struct that stores all the static vorbis bitstream
  20.             settings */
  21. vorbis_comment   vc; /* struct that stores all the bitstream user comments */
  22. vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
  23. vorbis_block     vb; /* local working space for packet->PCM decode */
  24.  
  25.  
  26.  
  27. int lame_decode_ogg_initfile(FILE *fd,mp3data_struct *mp3data)
  28. {
  29.  
  30.   
  31.   char *buffer;
  32.   int  bytes;
  33.   int i;
  34.  
  35.  
  36.   /********** Decode setup ************/
  37.  
  38.   ogg_sync_init(&oy); /* Now we can read pages */
  39.   
  40.  
  41.   /* grab some data at the head of the stream.  We want the first page
  42.      (which is guaranteed to be small and only contain the Vorbis
  43.      stream initial header) We need the first page to get the stream
  44.      serialno. */
  45.   
  46.   /* submit a 4k block to libvorbis' Ogg layer */
  47.   buffer=ogg_sync_buffer(&oy,4096);
  48.   bytes=fread(buffer,1,4096,fd);
  49.   ogg_sync_wrote(&oy,bytes);
  50.   
  51.   /* Get the first page. */
  52.   if(ogg_sync_pageout(&oy,&og)!=1){
  53.     /* error case.  Must not be Vorbis data */
  54.     ERRORF("Error initializing Ogg bitstream data.\n");
  55.     return -1;
  56.   }
  57.   
  58.   /* Get the serial number and set up the rest of decode. */
  59.   /* serialno first; use it to set up a logical stream */
  60.   ogg_stream_init(&os,ogg_page_serialno(&og));
  61.   
  62.   /* extract the initial header from the first page and verify that the
  63.      Ogg bitstream is in fact Vorbis data */
  64.   
  65.   /* I handle the initial header first instead of just having the code
  66.      read all three Vorbis headers at once because reading the initial
  67.      header is an easy way to identify a Vorbis bitstream and it's
  68.      useful to see that functionality seperated out. */
  69.   
  70.   vorbis_info_init(&vi);
  71.   vorbis_comment_init(&vc);
  72.   if(ogg_stream_pagein(&os,&og)<0){ 
  73.     /* error; stream version mismatch perhaps */
  74.     ERRORF("Error reading first page of Ogg bitstream data.\n");
  75.     return -1;
  76.   }
  77.   
  78.   if(ogg_stream_packetout(&os,&op)!=1){ 
  79.     /* no page? must not be vorbis */
  80.     ERRORF("Error reading initial header packet.\n");
  81.     return -1;
  82.   }
  83.   
  84.   if(vorbis_synthesis_headerin(&vi,&vc,&op)<0){ 
  85.     /* error case; not a vorbis header */
  86.     ERRORF("This Ogg bitstream does not contain Vorbis "
  87.         "audio data.\n");
  88.     return -1;
  89.   }
  90.   
  91.   /* At this point, we're sure we're Vorbis.  We've set up the logical
  92.      (Ogg) bitstream decoder.  Get the comment and codebook headers and
  93.      set up the Vorbis decoder */
  94.   
  95.   /* The next two packets in order are the comment and codebook headers.
  96.      They're likely large and may span multiple pages.  Thus we reead
  97.      and submit data until we get our two pacakets, watching that no
  98.      pages are missing.  If a page is missing, error out; losing a
  99.      header page is the only place where missing data is fatal. */
  100.   
  101.   i=0;
  102.   while(i<2){
  103.     while(i<2){
  104.       int result=ogg_sync_pageout(&oy,&og);
  105.       if(result==0)break; /* Need more data */
  106.       /* Don't complain about missing or corrupt data yet.  We'll
  107.      catch it at the packet output phase */
  108.       if(result==1){
  109.     ogg_stream_pagein(&os,&og); /* we can ignore any errors here
  110.                        as they'll also become apparent
  111.                        at packetout */
  112.     while(i<2){
  113.       result=ogg_stream_packetout(&os,&op);
  114.       if(result==0)break;
  115.       if(result==-1){
  116.         /* Uh oh; data at some point was corrupted or missing!
  117.            We can't tolerate that in a header.  Die. */
  118.         ERRORF("Corrupt secondary header.  Exiting.\n");
  119.         return -1;
  120.       }
  121.       vorbis_synthesis_headerin(&vi,&vc,&op);
  122.       i++;
  123.     }
  124.       }
  125.     }
  126.     /* no harm in not checking before adding more */
  127.     buffer=ogg_sync_buffer(&oy,4096);
  128.     bytes=fread(buffer,1,4096,fd);
  129.     if(bytes==0 && i<2){
  130.       ERRORF("End of file before finding all Vorbis headers!\n");
  131.       return -1;
  132.     }
  133.     ogg_sync_wrote(&oy,bytes);
  134.   }
  135.   
  136.   /* Throw the comments plus a few lines about the bitstream we're
  137.      decoding */
  138.   {
  139.     /*
  140.     char **ptr=vc.user_comments;
  141.     while(*ptr){
  142.       MSGF("%s\n",*ptr);
  143.       ++ptr;
  144.     }
  145.     MSGF("\nBitstream is %d channel, %ldHz\n",vi.channels,vi.rate);
  146.     MSGF("Encoded by: %s\n\n",vc.vendor);
  147.     */
  148.   }
  149.   
  150.   
  151.   /* OK, got and parsed all three headers. Initialize the Vorbis
  152.      packet->PCM decoder. */
  153.   vorbis_synthesis_init(&vd,&vi); /* central decode state */
  154.   vorbis_block_init(&vd,&vb);     /* local state for most of the decode
  155.                      so multiple block decodes can
  156.                      proceed in parallel.  We could init
  157.                      multiple vorbis_block structures
  158.                      for vd here */
  159.   
  160.   mp3data->stereo = vi.channels;
  161.   mp3data->samplerate = vi.rate;
  162.   mp3data->bitrate = 0; //ov_bitrate_instant(&vf);
  163.   mp3data->nsamp=MAX_U_32_NUM;
  164.   
  165.   return 0;
  166. }
  167.  
  168.  
  169.  
  170. /*
  171.   For lame_decode_fromfile:  return code
  172.   -1     error, or eof
  173.   0     ok, but need more data before outputing any samples
  174.   n     number of samples output.  
  175. */
  176. int lame_decode_ogg_fromfile(FILE *fd,short int pcm_l[],short int pcm_r[],mp3data_struct *mp3data)
  177. {
  178.   int samples,result,i,j,eof=0,eos=0,bout=0;
  179.   double **pcm;
  180.  
  181.  
  182.   while(1){
  183.  
  184.     /* 
  185.     **pcm is a multichannel double vector.  In stereo, for
  186.     example, pcm[0] is left, and pcm[1] is right.  samples is
  187.     the size of each channel.  Convert the float values
  188.     (-1.<=range<=1.) to whatever PCM format and write it out */
  189.     /* unpack the buffer, if it has at least 1024 samples */
  190.     convsize=1024;
  191.     samples=vorbis_synthesis_pcmout(&vd,&pcm);
  192.     if (samples >= convsize || eos || eof) {
  193.       /* read 1024 samples, or if eos, read what ever is in buffer */
  194.       int clipflag=0;
  195.       bout=(samples<convsize?samples:convsize);
  196.       
  197.       /* convert doubles to 16 bit signed ints (host order) and
  198.      interleave */
  199.       for(i=0;i<vi.channels;i++){
  200.     double  *mono=pcm[i];
  201.     for(j=0;j<bout;j++){
  202.       int val=mono[j]*32767.;
  203.       /* might as well guard against clipping */
  204.       if(val>32767){
  205.         val=32767;
  206.         clipflag=1;
  207.       }
  208.       if(val<-32768){
  209.         val=-32768;
  210.         clipflag=1;
  211.       }
  212.       if (i==0) pcm_l[j]=val;
  213.       if (i==1) pcm_r[j]=val;
  214.     }
  215.       }
  216.       
  217.       /*
  218.       if(clipflag)
  219.     MSGF("Clipping in frame %ld\n",vd.sequence);
  220.       */
  221.       
  222.       /* tell libvorbis how many samples we actually consumed */
  223.       vorbis_synthesis_read(&vd,bout); 
  224.       
  225.       break;
  226.     }    
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.     result=ogg_sync_pageout(&oy,&og);
  234.       
  235.     if(result==0) {
  236.       /* need more data */
  237.     }else if (result==-1){ /* missing or corrupt data at this page position */
  238.       ERRORF("Corrupt or missing data in bitstream; "
  239.           "continuing...\n");
  240.     }else{
  241.       /* decode this page */
  242.       ogg_stream_pagein(&os,&og); /* can safely ignore errors at
  243.                        this point */
  244.       do {
  245.     result=ogg_stream_packetout(&os,&op);
  246.     if(result==0) {
  247.       /* need more data */
  248.     } else if(result==-1){ /* missing or corrupt data at this page position */
  249.       /* no reason to complain; already complained above */
  250.     }else{
  251.       /* we have a packet.  Decode it */
  252.       vorbis_synthesis(&vb,&op);
  253.       vorbis_synthesis_blockin(&vd,&vb);
  254.     }
  255.       } while (result!=0);
  256.     }
  257.  
  258.     /* is this the last page? */    
  259.     if(ogg_page_eos(&og))eos=1;
  260.     
  261.     if(!eos){
  262.       char *buffer;
  263.       int bytes;
  264.       buffer=ogg_sync_buffer(&oy,4096);
  265.       bytes=fread(buffer,1,4096,fd);
  266.       ogg_sync_wrote(&oy,bytes);
  267.       if(bytes==0)eof=1;
  268.     }
  269.   }
  270.   
  271.  
  272.  
  273.   mp3data->stereo = vi.channels;
  274.   mp3data->samplerate = vi.rate;
  275.   mp3data->bitrate = 0; //ov_bitrate_instant(&vf);
  276.   /*  mp3data->nsamp=MAX_U_32_NUM;*/
  277.  
  278.   
  279.   if (bout==0) {
  280.     /* clean up this logical bitstream; before exit we see if we're
  281.        followed by another [chained] */
  282.     ogg_stream_clear(&os);
  283.     
  284.     /* ogg_page and ogg_packet structs always point to storage in
  285.        libvorbis.  They're never freed or manipulated directly */
  286.     
  287.     vorbis_block_clear(&vb);
  288.     vorbis_dsp_clear(&vd);
  289.     vorbis_info_clear(&vi);  /* must be called last */
  290.     
  291.     /* OK, clean up the framer */
  292.     ogg_sync_clear(&oy);
  293.     return -1;
  294.   }
  295.  
  296.   
  297.   return bout;
  298. }
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312. ogg_stream_state os2; /* take physical pages, weld into a logical
  313.             stream of packets */
  314. ogg_page         og2; /* one Ogg bitstream page.  Vorbis packets are inside */
  315. ogg_packet       op2; /* one raw packet of data for decode */
  316.  
  317. vorbis_info      vi2; /* struct that stores all the static vorbis bitstream
  318.             settings */
  319. vorbis_comment   vc2; /* struct that stores all the bitstream user comments */
  320. vorbis_dsp_state vd2; /* central working state for the packet->PCM decoder */
  321. vorbis_block     vb2; /* local working space for packet->PCM decode */
  322.  
  323.  
  324.  
  325.  
  326. int lame_encode_ogg_init(lame_global_flags *gfp)
  327. {
  328.   lame_internal_flags *gfc=gfp->internal_flags;
  329.  
  330.   
  331.   /********** Encode setup ************/
  332.   
  333.   /* choose an encoding mode */
  334.   /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
  335.   memcpy(&vi2,&info_A,sizeof(vi));
  336.   vi2.channels = gfc->stereo;
  337.   vi2.rate = gfp->out_samplerate;
  338.  
  339.   
  340.   /* add a comment */
  341.   vorbis_comment_init(&vc2);
  342.   vorbis_comment_add(&vc2,"Track encoded using L.A.M.E. libvorbis interface.");
  343.   
  344.   /* set up the analysis state and auxiliary encoding storage */
  345.   vorbis_analysis_init(&vd2,&vi2);
  346.   vorbis_block_init(&vd2,&vb2);
  347.   
  348.   /* set up our packet->stream encoder */
  349.   /* pick a random serial number; that way we can more likely build
  350.      chained streams just by concatenation */
  351.   srand(time(NULL));
  352.   ogg_stream_init(&os2,rand());
  353.   
  354.   /* Vorbis streams begin with three headers; the initial header (with
  355.      most of the codec setup parameters) which is mandated by the Ogg
  356.      bitstream spec.  The second header holds any comment fields.  The
  357.      third header holds the bitstream codebook.  We merely need to
  358.      make the headers, then pass them to libvorbis one at a time;
  359.      libvorbis handles the additional Ogg bitstream constraints */
  360.   
  361.   {
  362.     ogg_packet header;
  363.     ogg_packet header_comm;
  364.     ogg_packet header_code;
  365.     
  366.     vorbis_analysis_headerout(&vd2,&vc2,&header,&header_comm,&header_code);
  367.     ogg_stream_packetin(&os2,&header); /* automatically placed in its own
  368.                      page */
  369.     ogg_stream_packetin(&os2,&header_comm);
  370.     ogg_stream_packetin(&os2,&header_code);
  371.     
  372.     /* no need to write out here.  We'll get to that in the main loop */
  373.   }
  374.   
  375.   return 0;
  376. }
  377.  
  378.  
  379.  
  380. int lame_encode_ogg_finish(lame_global_flags *gfp,
  381.               char *mp3buf, int mp3buf_size)
  382. {
  383.   int eos=0,bytes=0;
  384.  
  385.   vorbis_analysis_wrote(&vd2,0);
  386.  
  387.   while(vorbis_analysis_blockout(&vd2,&vb2)==1){
  388.     
  389.     /* analysis */
  390.     vorbis_analysis(&vb2,&op2);
  391.  
  392.       /* weld the packet into the bitstream */
  393.       ogg_stream_packetin(&os2,&op2);
  394.  
  395.       /* write out pages (if any) */
  396.       while(!eos){
  397.     int result=ogg_stream_pageout(&os2,&og2);
  398.     if(result==0)break;
  399.  
  400.  
  401.     /* check if mp3buffer is big enough for the output */
  402.     bytes += og.header_len + og.body_len;
  403.     if (bytes > mp3buf_size && mp3buf_size>0)
  404.       return -5;
  405.     
  406.     memcpy(mp3buf,og.header,og.header_len);
  407.     memcpy(mp3buf+og.header_len,og.body,og.body_len);
  408.  
  409.     /* this could be set above, but for illustrative purposes, I do
  410.        it here (to show that vorbis does know where the stream ends) */
  411.     if(ogg_page_eos(&og2))eos=1;
  412.  
  413.       }
  414.     }
  415.  
  416.  
  417.   /* clean up and exit.  vorbis_info_clear() must be called last */
  418.   ogg_stream_clear(&os2);
  419.   vorbis_block_clear(&vb2);
  420.   vorbis_dsp_clear(&vd2);
  421.  
  422.   
  423.   /* ogg_page and ogg_packet structs always point to storage in
  424.      libvorbis.  They're never freed or manipulated directly */
  425.   return bytes;
  426.  
  427. }
  428.  
  429.  
  430.  
  431. int lame_encode_ogg_frame(lame_global_flags *gfp,
  432.               short int inbuf_l[],short int inbuf_r[],
  433.               char *mp3buf, int mp3buf_size)
  434. {
  435.  
  436.   lame_internal_flags *gfc=gfp->internal_flags;
  437.   long i;
  438.   int eos=0;
  439.   int bytes=0;
  440.   
  441.   /* expose the buffer to submit data */
  442.   double **buffer=vorbis_analysis_buffer(&vd2,gfp->framesize);
  443.   
  444.   /* uninterleave samples */
  445.   for(i=0;i<gfp->framesize;i++){
  446.     buffer[0][i]=(double)inbuf_l[i]/32768.0;
  447.     if (gfc->stereo==2)
  448.       buffer[1][i]=(double)inbuf_r[i]/32768.0;
  449.   }
  450.   
  451.   /* tell the library how much we actually submitted */
  452.   vorbis_analysis_wrote(&vd2,i);
  453.  
  454.   /* vorbis does some data preanalysis, then divvies up blocks for
  455.      more involved (potentially parallel) processing.  Get a single
  456.      block for encoding now */
  457.   while(vorbis_analysis_blockout(&vd2,&vb2)==1){
  458.     int result;
  459.     /* analysis */
  460.     vorbis_analysis(&vb2,&op2);
  461.     
  462.     /* weld the packet into the bitstream */
  463.     ogg_stream_packetin(&os,&op2);
  464.     
  465.     /* write out pages (if any) */
  466.     do {
  467.       result=ogg_stream_pageout(&os,&og2);
  468.       if (result==0) break;
  469.     
  470.       /* check if mp3buffer is big enough for the output */
  471.       bytes += og.header_len + og.body_len;
  472.       DEBUGF("\n\n*********\ndecoded bytes=%i  %i \n",bytes,mp3buf_size);
  473.       if (bytes > mp3buf_size && mp3buf_size>0)
  474.     return -6;
  475.       
  476.       /*
  477.     fwrite(og.header,1,og.header_len,stdout);
  478.     fwrite(og.body,1,og.body_len,stdout);
  479.       */
  480.       memcpy(mp3buf,og.header,og.header_len);
  481.       memcpy(mp3buf+og.header_len,og.body,og.body_len);
  482.       mp3buf += og.header_len + og.body_len;
  483.       
  484.       if(ogg_page_eos(&og2))eos=1;
  485.     } while (1);
  486.   }
  487.   gfp->frameNum++;
  488.   return bytes;
  489. }
  490.  
  491.  
  492.  
  493.  
  494. #endif
  495.